#include <iostream>
#include <unistd.h>
#include <thread>
#include <atomic>
#include <future>

int add()
{
	std::cout << "add开始异步调用" << std::endl;
	return 1 + 1;
}

int add1(int a, int b)
{
	std::cout << "add1开始异步调用" << std::endl;
	return a + b;
}

void do_other()
{
	std::cout << "调用do_other" << std::endl;
	sleep(3);
}

// future 与 aysnc的使用
void test1()
{
	std::future<int> result = std::async(add); // 封装任务，此时并没有允许
	// auto result = std::async(add); 方便的写法

	do_other();
	std::cout << "执行异步调用,获取线程操作的结果:" << result.get() << std::endl;

	// 如果需要传递参数
	std::future<int> result1 = std::async(add1, 3, 5);
	do_other();
	std::cout << "执行异步调用,获取线程操作的结果:" << result1.get() << std::endl;
}

// packaged_task的使用
void test2()
{
	// 进行函数包装
	std::packaged_task<int(int, int)> task(add1);
	// 先获取结果再去执行其他任务
	std::future<int> result = task.get_future();
	do_other();
	// 执行任务
	task(3, 5);
	std::cout << "执行异步调用,获取线程操作的结果:" << result.get() << std::endl;
}

// promise的使用
void print(std::promise<std::string> &p)
{
	std::cout << "promise线程正在获取结果" << std::endl;
	sleep(2);
	std::cout << "promise线程成功获取结果" << std::endl;
	p.set_value("Hello world"); // 将执行print函数的线程获取的结果给promise
}

void test3()
{
	// 使用promise获取future
	// 首先设置promise
	std::promise<std::string> pm;
	// 通过promise获取future
	std::future<std::string> result = pm.get_future();

	std::thread t1(print, std::ref(pm));
	do_other();
	std::cout << "执行异步调用,获取线程操作的结果:" << result.get() << std::endl; // 主线程等待返回
	t1.join();
}

int main()
{
	// test1();
	// test2();
	test3();
}